package com.klm.easymq.service.impl;

import com.klm.easymq.config.EasyMqProperties;
import com.klm.easymq.core.IdempotentHandler;
import com.klm.easymq.core.MessageSerializer;
import com.klm.easymq.core.MonitorService;
import com.klm.easymq.service.EasyMqService;
import com.klm.easymq.service.RocketMQProducerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * Easy-MQ 核心服务实现
 * 集成所有功能模块，提供统一的消息服务
 */
@Slf4j
@Service
public class EasyMqServiceImpl implements EasyMqService {
    
    private final EasyMqProperties properties;
    private final MessageSerializer messageSerializer;
    private final IdempotentHandler idempotentHandler;
    private final MonitorService monitorService;
    
    @Autowired(required = false)
    private RocketMQProducerService rocketMqProducerService;
    
    public EasyMqServiceImpl(EasyMqProperties properties, 
                           MessageSerializer messageSerializer,
                           IdempotentHandler idempotentHandler,
                           MonitorService monitorService) {
        this.properties = properties;
        this.messageSerializer = messageSerializer;
        this.idempotentHandler = idempotentHandler;
        this.monitorService = monitorService;
    }
    
    @Override
    public boolean sendSync(String topic, Object message) {
        return sendSync(topic, message, "", "");
    }
    
    @Override
    public boolean sendSync(String topic, Object message, String tag, String messageKey) {
        try {
            // 生成追踪ID
            String traceId = generateTraceId();
            
            // 序列化消息
            byte[] messageBytes = messageSerializer.serialize(message);
            String messageStr = new String(messageBytes);
            
            // 记录发送开始
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, "SENDING");
            }
            
            // 发送消息
            boolean result = false;
            if (rocketMqProducerService != null) {
                result = rocketMqProducerService.sendSyncMessage(topic, messageStr, tag, messageKey);
            }
            
            // 记录发送结果
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, result ? "SUCCESS" : "FAILED");
            }
            
            log.info("同步消息发送完成: topic={}, traceId={}, result={}", topic, traceId, result);
            return result;
            
        } catch (Exception e) {
            log.error("同步消息发送失败: topic={}, message={}", topic, message, e);
            return false;
        }
    }
    
    @Override
    public void sendAsync(String topic, Object message) {
        sendAsync(topic, message, "", "");
    }
    
    @Override
    public void sendAsync(String topic, Object message, String tag, String messageKey) {
        try {
            // 生成追踪ID
            String traceId = generateTraceId();
            
            // 序列化消息
            byte[] messageBytes = messageSerializer.serialize(message);
            String messageStr = new String(messageBytes);
            
            // 记录发送开始
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, "SENDING");
            }
            
            // 发送消息
            if (rocketMqProducerService != null) {
                rocketMqProducerService.sendAsyncMessage(topic, messageStr, tag, messageKey);
            }
            
            log.info("异步消息发送完成: topic={}, traceId={}", topic, traceId);
            
        } catch (Exception e) {
            log.error("异步消息发送失败: topic={}, message={}", topic, message, e);
        }
    }
    
    @Override
    public boolean sendDelay(String topic, Object message, int delayLevel) {
        try {
            // 生成追踪ID
            String traceId = generateTraceId();
            
            // 序列化消息
            byte[] messageBytes = messageSerializer.serialize(message);
            String messageStr = new String(messageBytes);
            
            // 记录发送开始
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, "SENDING_DELAY");
            }
            
            // 发送延迟消息
            boolean result = false;
            if (rocketMqProducerService != null) {
                result = rocketMqProducerService.sendDelayMessage(topic, messageStr, delayLevel);
            }
            
            // 记录发送结果
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, result ? "SUCCESS" : "FAILED");
            }
            
            log.info("延迟消息发送完成: topic={}, traceId={}, delayLevel={}, result={}", 
                    topic, traceId, delayLevel, result);
            return result;
            
        } catch (Exception e) {
            log.error("延迟消息发送失败: topic={}, message={}, delayLevel={}", topic, message, delayLevel, e);
            return false;
        }
    }
    
    @Override
    public boolean sendOrdered(String topic, Object message, String hashKey) {
        try {
            // 生成追踪ID
            String traceId = generateTraceId();
            
            // 序列化消息
            byte[] messageBytes = messageSerializer.serialize(message);
            String messageStr = new String(messageBytes);
            
            // 记录发送开始
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, "SENDING_ORDERED");
            }
            
            // 发送顺序消息
            boolean result = false;
            if (rocketMqProducerService != null) {
                result = rocketMqProducerService.sendOrderedMessage(topic, messageStr, hashKey);
            }
            
            // 记录发送结果
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, result ? "SUCCESS" : "FAILED");
            }
            
            log.info("顺序消息发送完成: topic={}, traceId={}, hashKey={}, result={}", 
                    topic, traceId, hashKey, result);
            return result;
            
        } catch (Exception e) {
            log.error("顺序消息发送失败: topic={}, message={}, hashKey={}", topic, message, hashKey, e);
            return false;
        }
    }
    
    @Override
    public void sendOneway(String topic, Object message, String tag, String messageKey) {
        try {
            // 生成追踪ID
            String traceId = generateTraceId();
            
            // 序列化消息
            byte[] messageBytes = messageSerializer.serialize(message);
            String messageStr = new String(messageBytes);
            
            // 记录发送开始
            if (monitorService != null) {
                monitorService.recordMessageSend(traceId, topic, messageStr, "SENDING_ONEWAY");
            }
            
            // 发送单向消息
            if (rocketMqProducerService != null) {
                rocketMqProducerService.sendOnewayMessage(topic, messageStr, tag, messageKey);
            }
            
            log.info("单向消息发送完成: topic={}, traceId={}", topic, traceId);
            
        } catch (Exception e) {
            log.error("单向消息发送失败: topic={}, message={}", topic, message, e);
        }
    }
    
    @Override
    public EasyMqProperties getProperties() {
        return properties;
    }
    
    @Override
    public boolean isHealthy() {
        // 检查各个组件是否正常
        boolean rocketMqHealthy = rocketMqProducerService != null;
        boolean serializerHealthy = messageSerializer != null;
        boolean idempotentHealthy = idempotentHandler != null || !properties.getIdempotent().isEnabled();
        boolean monitorHealthy = monitorService != null || !properties.getMonitor().isEnabled();
        
        return rocketMqHealthy && serializerHealthy && idempotentHealthy && monitorHealthy;
    }
    
    /**
     * 生成追踪ID
     * @return 追踪ID
     */
    private String generateTraceId() {
        return "easy-mq-" + UUID.randomUUID().toString().replace("-", "");
    }
} 